package com.apes.framework.plugin.outbox;

import com.apes.framework.jpa.DefaultPersistListener;
import com.apes.framework.jpa.Model;
import com.apes.framework.jpa.comment.Comment;
import com.apes.framework.jpa.generator.ApesGenerator;
import com.apes.framework.plugin.soe.annotations.State;
import com.apes.framework.plugin.soe.annotations.States;
import com.apes.framework.rop.session.SessionUtil;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.SelectBeforeUpdate;
import org.springframework.util.StringUtils;

import javax.persistence.*;
import java.util.Objects;
import java.util.function.Function;

/**
 * 功能：订阅者
 *
 * @author xul
 * @create 2019-10-24 10:57
 */
@Getter
@Setter
@SelectBeforeUpdate
@DynamicInsert
@DynamicUpdate
@Entity
@EntityListeners(DefaultPersistListener.class)
@Table(name = OutboxSubscriber.CONST_TABLE_NAME, indexes = {
        @Index(columnList = "event_type, aggregate_type")})
public class OutboxSubscriber extends Model {
    public final static String CONST_TABLE_NAME = "outbox_subscriber";

    @Id
    @Column(name = "id", length = 32)
    @ApesGenerator(code = CONST_TABLE_NAME, name = "发件箱订阅者")
    private String id;

    @Column(name = "name", length = 128)
    @Comment("描述")
    private String name;

    @Column(name = "condition", length = 128)
    @Comment("执行条件")
    private String condition;

    @States(name = "事件事件", values = {
            @State(id = "S", name = "实体保存事件"),
            @State(id = "D", name = "实体删除事件")})
    @Column(name = "event_type", length = 64, nullable = false)
    @Comment("事件类型")
    private String eventType;

    @Column(name = "aggregate_type", length = 128)
    @Comment("聚合根类型")
    private String aggregateType;

    @Column(name = "consumer_event", length = 128, nullable = false)
    @Comment("消费者")
    private String consumer;

    public String getAggregateType() {
        return getAggregateType(aggregateType);
    }

    public void setAggregateType(String aggregateType) {
        this.aggregateType = getAggregateType(aggregateType);
    }

    private String getAggregateType(String aggregateType) {
        return StringUtils.isEmpty(aggregateType) ? "*" : aggregateType;
    }

    @Transient
    public String cacheId() {
        return SessionUtil.getSessionId(getEventType(), getAggregateType());
    }

    @Transient
    private Function processor;

    @Transient
    private boolean readonly = false;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        OutboxSubscriber that = (OutboxSubscriber) o;
        return id.equals(that.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}
